﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Web.Mvc;
using DotNet.Highcharts;
using DotNet.Highcharts.Enums;
using DotNet.Highcharts.Helpers;
using DotNet.Highcharts.Options;
using Mondial2014.Models.Competition;
using Mondial2014.Models.Context;
using Mondial2014.Utils.Extensions;

namespace Mondial2014.Controllers
{
    public class StatsController : Controller
    {
        #region context
        private readonly Mondial2014DbContext m_Context = new Mondial2014DbContext();
        #endregion

        #region Index

        // GET: Stats
        public ActionResult Index()
        {
            return View();
        }

        #endregion

        #region QualifiersStats

        public class QualifiersStatsViewModel
        {
            public Highcharts WinnersHighcharts { get; set; }
            public Highcharts FinalsHighcharts { get; set; }
            public Highcharts SemisHighcharts { get; set; }
            public Highcharts QuarterssHighcharts { get; set; }
            public Highcharts Last16SHighcharts { get; set; }
        }

        public ActionResult QualifiersStats()
        {
            var model = new QualifiersStatsViewModel
            {
                WinnersHighcharts =
                    CreateWinnersHighcharts(GetQualifiersForStage(StageType.Winner), "winners", "מי תזכה"),
                FinalsHighcharts = 
                    CreateWinnersHighcharts(GetQualifiersForStage(StageType.Final), "Finals", "מי תעלה לגמר"),
                SemisHighcharts =
                    CreateWinnersHighcharts(GetQualifiersForStage(StageType.Semi), "semis", "מי תעלה לחצי"),
                QuarterssHighcharts =
                    CreateWinnersHighcharts(GetQualifiersForStage(StageType.Quarter), "quarters", "מי תעלה לרבע"),
                Last16SHighcharts =
                    CreateWinnersHighcharts(GetQualifiersForStage(StageType.Last16), "last16s", "מי תעלה לשמינית")
            };

            return View(model);
        }

        public IQueryable<IGrouping<string, string>> GetQualifiersForStage(StageType stageType)
        {
            return m_Context.KnockoutGambles
                .Where(g => g.Stage.Level == (int)stageType && g.Team != null)
                .Select(g => g.Team.Name)
                .GroupBy(name => name);
        }

        public Highcharts CreateWinnersHighcharts(IQueryable<IGrouping<string,string>> stats, string chartName, string chartDisplayName)
        {
            stats = stats.OrderBy(g => g.Count());
            var groupNames = stats.Select(g => g.Key).ToArray();
            var groupCounts = stats.Select(g => g.Count()).ToArray();

            return new Highcharts(chartName)
                .InitChart(new Chart { DefaultSeriesType = ChartTypes.Column})
                .SetTitle(new Title { Text = chartDisplayName })
                .SetXAxis(new XAxis { Categories = groupNames })
                .SetYAxis(new YAxis { Title = new YAxisTitle { Text = "מספר משתתפים" } })
                .SetPlotOptions(new PlotOptions
                {
                    Line = new PlotOptionsLine
                    {
                        DataLabels = new PlotOptionsLineDataLabels
                        {
                            Enabled = true
                        },
                        EnableMouseTracking = true
                    }
                })
                .SetSeries(new[]
                {
                    new Series { Name = "קבוצות", Data = new Data( groupCounts.Cast<object>().ToArray() )}
                });
        }

        #endregion

        #region GammesResultsStats

        public class GameResultStatsViewModel
        {
            public int GameNumber       { get; set; }
            public string Date          { get; set; }
            public string Team1Name     { get; set; }
            public string Team2Name     { get; set; }
            public FixtureResult Result { get; set; }
            public double Percent1      { get; set; }
            public double Percent2      { get; set; }
            public double PercentX      { get; set; }
        }

        public ActionResult GammesResultsStats()
        {
            var models = new List<GameResultStatsViewModel>();
            foreach (var fixtureIterator in m_Context.GetFixtures().OrderBy(f => f.Number).ToArray())
            {
                var fixture = fixtureIterator;

                var fixtureGambles = m_Context.GameGambles.Where(gg => gg.Fixture.Number == fixture.Number);
                var totalGambles = fixtureGambles.Count();
                var team1Gambles = fixtureGambles.Count(g => g.FixtureResult == FixtureResult.Team1);
                var team2Gambles = fixtureGambles.Count(g => g.FixtureResult == FixtureResult.Team2);
                var xGambles = fixtureGambles.Count(g => g.FixtureResult == FixtureResult.Tie);

                var model = new GameResultStatsViewModel
                {
                    GameNumber = fixture.Number,
                    Date = fixture.Date.ToString("d.MM"),
                    Team1Name = fixture.Team1.Name,
                    Team2Name = fixture.Team2.Name,
                    Result = fixture.GetGameResult(),
                    Percent1 = ((double)team1Gambles / totalGambles) * 100,
                    Percent2 = ((double)team2Gambles / totalGambles) * 100,
                    PercentX = ((double)xGambles / totalGambles) * 100
                };

                models.Add(model);
            }

            return View(models);
        }

        #endregion

        #region Chart example

        private Highcharts GetCharHighcharts(int index)
        {
            return new Highcharts("chart" + index)
                //define the type of chart
                .InitChart(new Chart { DefaultSeriesType = ChartTypes.Line })
                //overall title of the chart
                .SetTitle(new Title { Text = "Gambling Stats" })
                //small label below the main Title
                .SetSubtitle(new Subtitle { Text = "stats team" })
                //load the x values
                .SetXAxis(new XAxis { Categories = new[] { "Brazil", "Croatia", "Holand" } })
                //set the Y title
                .SetYAxis(new YAxis { Title = new YAxisTitle { Text = "Number of Wins" } })
                .SetTooltip(new Tooltip
                {
                    Enabled = true,
                    Formatter = @"function() { return '<b>' + this.series.name + '</b><br/>' + this.x + ': ' + this.y }"
                })
                .SetPlotOptions(new PlotOptions
                {
                    Line = new PlotOptionsLine
                    {
                        DataLabels = new PlotOptionsLineDataLabels
                        {
                            Enabled = true
                        },
                        EnableMouseTracking = true
                    }
                })
                // load the Y values
                .SetSeries(new[]
                {
                    new Series { Name = "Wins", Data = new Data(new object[] { 1, 2, 3 })}
                });
        }

        #endregion
    }
}